# -*- coding: UTF-8 -*-
import md5
import os

from pyramid.response import Response
from pyramid.view import view_config
from pyramid.renderers import render_to_response
from pyramid.httpexceptions import HTTPFound
from pyramid.security import (
        remember,
        forget,
        IAuthenticationPolicy,
        )

from sqlalchemy.exc import DBAPIError
from sqlalchemy import and_, or_, desc

from ..models.meta import (
    DBSession,
    )

from ..models.models import (
    User,
    Role,
    BusinessUser,
    Coupon,
    ProductCategory,
    Product,
    ProductOrder
    )

from ..lib.utils import upload
from ..freedom.paginator import Paginator
from ..freedom.searchhelper import addSearchFilters
from ..freedom.dateutil.parser import parse

pagesize = 20



@view_config(route_name='admin_login')
def adminlogin(request):
    came_from = request.params.get('came_from', request.route_url('admin_index'))
    name = request.params.get('name', '')
    password = request.params.get('password', '')
    if(name and password):
        user_q = DBSession().query(User)
        if(user_q.filter(User.name == name).filter(User.password == md5.new(password).hexdigest()).filter(User.roleid==1).count() > 0):
            request.session['user_name'] = name
            headers = remember(request, 'role:admin')
            return HTTPFound(location = came_from, headers = headers)
    return render_to_response('/admin/login.html', {}, request = request)


@view_config(route_name='admin_top', permission="admin_view")
def admintop(request):
    #username = request.registry.queryUtility(IAuthenticationPolicy).authenticated_userid(request)
    tmpl_context = {'username': request.session.get('user_name')}
    return render_to_response('/admin/top.html', tmpl_context, request = request)


@view_config(route_name='admin_index', permission="admin_view")
@view_config(route_name='admin_page', permission="admin_view")
def adminindex(request):
    page = request.matchdict.get('page', 'adminindex')
    tmpl_context = {}
    return render_to_response('/admin/%s.html' % page, tmpl_context, request = request)

@view_config(route_name='admin_module_menu', permission="admin_view")
def admin_moduler_menu(request):
    module = request.matchdict['module']
    tmpl_context = {}
    return render_to_response('/admin/%s/menu.html' % module, tmpl_context, request = request)


#user view
@view_config(route_name='admin_user_list', permission="admin_view")
def admin_user_list(request):
    role = request.params.get('role')
    user_q = DBSession().query(User).join(User.role).filter(Role.name == u'normal').order_by(desc(User.id))
    #search filter
    execcode, search_fields = addSearchFilters(request)
    for code in execcode:
        exec(code.replace('query', 'user_q'))

    #pagination
    paginator = Paginator(user_q, pagesize)
    paginator.page_from_url(request.url)
    tmpl_context = {'users':paginator, 'search_fields': search_fields}

    return render_to_response('/admin/user/list.html', tmpl_context, request = request)

@view_config(route_name='admin_user_edit', permission="admin_view")
def admin_user_edit(request):
    #submit from add/edit
    if 'form.submitted' in request.params:
        user = User()
        #edit
        if 'id' in request.params:
            user_q = DBSession.query(User)
            user = user_q.get(int(request.params.get('id')))
        #new
        else:
            user.name = request.params.get('name')
            user.password = md5.new(request.params.get('password')).hexdigest()
            user.role = DBSession.query(Role).filter(Role.name == request.params.get('role')).first()

        user.realname = request.params.get('realname')
        user.gender = int(request.params.get('gender'))
        user.subject = request.params.get('subject')
        user.schoolnumber = request.params.get('schoolnumber')
        user.email = request.params.get('email')
        user.tel = request.params.get('tel')
        user.checked = request.params.get('checked') and True or False
        user.enable = request.params.get('enable') and True or False
       
        DBSession.add(user)

        return HTTPFound(location = request.url.replace('edit.html', 'list.html'))

    #render add/edit
    recordid = request.params.get('id')
    tmpl_context = {'id':recordid, 'user':None}
    if recordid:
        tmpl_context['user'] = DBSession.query(User).get(recordid)
    return render_to_response('/admin/user/edit.html', tmpl_context, request = request)

@view_config(route_name='admin_user_delete', permission="admin_view")
def admin_user_delete(request):
    recordids = [int(id) for id in request.params.get('id').split(',') if id.strip()!='']
    DBSession.query(User).filter(User.id.in_(recordids)).delete(synchronize_session='fetch')

    return HTTPFound(location = request.url.replace('delete.html', 'list.html'))

#business user view
@view_config(route_name='admin_businessuser_list', permission="admin_view")
def admin_businessuser_list(request):
    role = request.params.get('role')
    businessuser_q = DBSession().query(BusinessUser).order_by(desc(BusinessUser.id))
    #search filter
    execcode, search_fields = addSearchFilters(request)
    for code in execcode:
        exec(code.replace('query', 'businessuser_q'))

    #pagination
    paginator = Paginator(businessuser_q, pagesize)
    paginator.page_from_url(request.url)
    tmpl_context = {'businessusers':paginator, 'search_fields': search_fields}

    return render_to_response('/admin/businessuser/list.html', tmpl_context, request = request)

@view_config(route_name='admin_businessuser_edit', permission="admin_view")
def admin_businessuser_edit(request):
    #submit from add/edit
    if 'form.submitted' in request.params:
        user = BusinessUser()
        #edit
        if 'id' in request.params:
            businessuser_q = DBSession.query(BusinessUser)
            user = businessuser_q.get(int(request.params.get('id')))
        #new
        else:
            user.login = request.params.get('login')
            user.password = md5.new(request.params.get('password')).hexdigest()

        user.companyname = request.params.get('companyname')
        user.businesstype = int(request.params.get('businesstype'))
        user.email = request.params.get('email')
        user.contactname = request.params.get('contactname')
        user.contacttel = request.params.get('contacttel')
        user.qq = request.params.get('qq')
        user.othercontacttool = request.params.get('othercontacttool')
        user.address = request.params.get('address')
        user.introduce = request.params.get('introduce')
        user.special = request.params.get('special')

        uploadfilename = upload(request.params.get('picture'), _getuploadpath(request), {}, 100)
        user.picture = uploadfilename and os.path.join(_getuploadurlpath(request), uploadfilename) or user.picture 

        user.checked = request.params.get('checked') and True or False
        user.enable = request.params.get('enable') and True or False
       
        DBSession.add(user)

        return HTTPFound(location = request.url.replace('edit.html', 'list.html'))

    #render add/edit
    recordid = request.params.get('id')
    tmpl_context = {'id':recordid, 'user':None}
    if recordid:
        tmpl_context['businessuser'] = DBSession.query(BusinessUser).get(recordid)
    return render_to_response('/admin/businessuser/edit.html', tmpl_context, request = request)


@view_config(route_name='admin_businessuser_delete', permission="admin_view")
def admin_businessuser_delete(request):
    recordids = [int(id) for id in request.params.get('id').split(',') if id.strip()!='']
    users = DBSession.query(BusinessUser).filter(BusinessUser.id.in_(recordids)).delete(synchronize_session='fetch')

    return HTTPFound(location = request.url.replace('delete.html', 'list.html'))


#coupon view
@view_config(route_name='admin_coupon_list', permission="admin_view")
def admin_coupon_list(request):
    status = int(request.params.get('status') or -1)
    deleted = request.params.get('deleted') and True or False

    coupon_q = DBSession().query(Coupon).filter(Coupon.status==status).filter(Coupon.deleted==deleted).order_by(desc(Coupon.createdate))
    #search filter
    execcode, search_fields = addSearchFilters(request)
    for code in execcode:
        exec(code.replace('query', 'coupon_q'))

    #pagination
    paginator = Paginator(coupon_q, pagesize)
    paginator.page_from_url(request.url)
    tmpl_context = {'coupons':paginator, 'search_fields': search_fields}

    from ..freedom.selecttablelist import get_table_options
    get_table_options('BusinessUser', 'id', 'companyname', '')

    return render_to_response('/admin/coupon/list.html', tmpl_context, request = request)


@view_config(route_name='admin_coupon_edit', permission="admin_view")
def admin_coupon_edit(request):
    #submit from add/edit
    if 'form.submitted' in request.params:
        coupon = Coupon()
        #edit
        if 'id' in request.params:
            coupon_q = DBSession.query(Coupon)
            coupon = coupon_q.get(int(request.params.get('id')))
        #new
        else:
            coupon.name = request.params.get('name')
            coupon.coupontype = int(request.params.get('coupontype'))
            coupon.businessUser_id = int(request.params.get('businessUser_id'))

        coupon.detail = request.params.get('detail')
        coupon.number = int(request.params.get('number'))
        coupon.rule = request.params.get('rule')
        coupon.startdate = parse(request.params.get('startdate'))
        coupon.enddate = parse(request.params.get('enddate'))

        uploadfilename = upload(request.params.get('picture'), _getuploadpath(request))
        coupon.picture = uploadfilename and os.path.join(_getuploadurlpath(request), uploadfilename) or (coupon.picture or '')

        coupon.status = request.params.get('action') == 'publish' and 3 or coupon.status

        DBSession.add(coupon)

        return HTTPFound(location = request.url.replace('edit.html', 'list.html'))

    #render add/edit
    recordid = request.params.get('id')
    tmpl_context = {'id':recordid}
    if recordid:
        tmpl_context['coupon'] = DBSession.query(Coupon).get(recordid)
    return render_to_response('/admin/coupon/edit.html', tmpl_context, request = request)


@view_config(route_name='admin_productcategory_list', permission="admin_view")
def admin_productcategory_list(request):
    category_q = DBSession.query(ProductCategory).filter(ProductCategory.category_id == None).order_by(ProductCategory.priority)

    #pagination
    paginator = Paginator(category_q, pagesize)
    paginator.page_from_url(request.url)
    tmpl_context = {'categories':paginator}

    return render_to_response('/admin/productcategory/list.html', tmpl_context, request = request)


@view_config(route_name='admin_productcategory_edit', permission="admin_view")
def admin_productcategory_edit(request):
    #submit from add/edit
    if 'form.submitted' in request.params:
        category = ProductCategory()
        #edit
        if 'id' in request.params:
            category_q = DBSession.query(ProductCategory)
            category = category_q.get(int(request.params.get('id')))
        #new
        else:
            category.name = request.params.get('name')
        category.priority = float(request.params.get('priority') or 1)

        DBSession.add(category)

        return HTTPFound(location = request.url.replace('edit.html', 'list.html'))

    #render add/edit
    recordid = request.params.get('id')
    tmpl_context = {'id':recordid}
    if recordid:
        tmpl_context['category'] = DBSession.query(ProductCategory).get(recordid)
    return render_to_response('/admin/productcategory/edit.html', tmpl_context, request = request)


@view_config(route_name='admin_productcategory_delete', permission="admin_view")
def admin_productcategory_delete(request):
    recordids = [int(id) for id in request.params.get('id').split(',') if id.strip()!='']
    DBSession.query(ProductCategory).filter(ProductCategory.id.in_(recordids)).delete(synchronize_session='fetch')

    return HTTPFound(location = request.url.replace('delete.html', 'list.html'))


@view_config(route_name='admin_product_list', permission="admin_view")
def admin_product_list(request):
    product_q = DBSession.query(Product).filter(Product.deleted == False)

    #pagination
    paginator = Paginator(product_q, pagesize)
    paginator.page_from_url(request.url)
    tmpl_context = {'products':paginator}

    return render_to_response('/admin/products/list.html', tmpl_context, request = request)

@view_config(route_name='admin_product_edit', permission="admin_view")
def admin_product_edit(request):
    #submit from add/edit
    if 'form.submitted' in request.params:
        product = Product()
        #edit
        if 'id' in request.params:
            product_q = DBSession.query(Product)
            product = product_q.get(int(request.params.get('id')))

        product.name = request.params.get('name')
        product.marketprice = float(request.params.get('marketprice'))
        product.sellprice = float(request.params.get('sellprice'))
        product.shortdetail = request.params.get('shortdetail')
        product.detail = request.params.get('detail')
        product.enable = request.params.get('enable') and True or False
        product.recommended = request.params.get('recommended') and True or False
        product.category_id = request.params.get('category_id')
        uploadfilename = upload(request.params.get('picture'), _getuploadpath(request), {}, 100)
        product.picture = uploadfilename and os.path.join(_getuploadurlpath(request), uploadfilename) or product.picture
       
        DBSession.add(product)

        return HTTPFound(location = request.url.replace('edit.html', 'list.html'))

    #render add/edit
    recordid = request.params.get('id')
    tmpl_context = {'id':recordid, 'product':None}
    if recordid:
        tmpl_context['product'] = DBSession.query(Product).get(recordid)
    return render_to_response('/admin/products/edit.html', tmpl_context, request = request)


@view_config(route_name='admin_product_delete', permission="admin_view")
def admin_product_delete(request):
    recordids = [int(id) for id in request.params.get('id').split(',') if id.strip()!='']
    DBSession.query(Product).filter(Product.id.in_(recordids)).update({'deleted':True},synchronize_session='fetch')

    return HTTPFound(location = request.url.replace('delete.html', 'list.html'))


@view_config(route_name='admin_productorder_list', permission="admin_view")
def admin_productorder_list(request):
    productorder_q = DBSession().query(ProductOrder).order_by(desc(ProductOrder.createdate))
    #search filter
    execcode, search_fields = addSearchFilters(request)
    for code in execcode:
        exec(code.replace('query', 'productorder_q'))

    #pagination
    paginator = Paginator(productorder_q, pagesize)
    paginator.page_from_url(request.url)
    tmpl_context = {'productorders':paginator, 'search_fields': search_fields}

    return render_to_response('/admin/productorder/list.html', tmpl_context, request = request)

@view_config(route_name='admin_productorder_edit', permission="admin_view")
def admin_productorder_edit(request):
    #submit from add/edit
    if 'form.submitted' in request.params:
        #edit
        productOrder_q = DBSession.query(ProductOrder)
        productOrder = productOrder_q.get(int(request.params.get('id')))

        orderstatus = int(request.params.get('orderStatus'))
        if productOrder.orderStatus > orderstatus:
            raise Exception('You can not roll back to old order status. order: %d, %s' % (productOrder.id, productOrder.orderSN))
        productOrder.orderStatus = orderstatus
        DBSession.add(productOrder)

        return HTTPFound(location = request.url.replace('edit.html', 'list.html'))

    #render add/edit
    recordid = request.params.get('id')
    tmpl_context = {'id':recordid, 'productOrder':None}
    if recordid:
        tmpl_context['productOrder'] = DBSession.query(ProductOrder).get(recordid)
    return render_to_response('/admin/productorder/edit.html', tmpl_context, request = request)


def _getuploadpath(request):
    return request.registry.settings.get('adminupload.root')

def _getuploadurlpath(request):
    return '/static/admin/upload/'
